import {
  config
} from "./config";
import axios from "axios";
import storage from "../utils/storage";
import {
  getRefresh
} from "../service/modules/user";
import useUserStore from "../store/modules/user";
let notUseTokenUrl = ["/auth/oauth/token"];
// import router from "../router/index.js";

class Request {
  http = {
    tokenName: "token",
    contentType: "application/json; charset=UTF-8",
  };
  http2 = {
    tokenName: "token",
    contentType: "multipart/form-data; charset=UTF-8",
  };
  http3 = {
    tokenName: "Authorization",
    contentType: "multipart/form-data; charset=UTF-8",
  };
  http4 = {
    tokenName: "Authorization",
    contentType: "application/json;charset=UTF-8",
  };

  curOption = {};
  requestArr = [];
  isRefreshing = false;
  stashConfig = {};
  constructor(option) {
    this.curOption = option;
  }
  request(opts, option) {
    const instance = axios.create(config);
    this.setInterceptors(instance, option);
    return instance(opts);
  }
  //拦截器
  setInterceptors(instance, option) {
    //请求拦截器
    instance.interceptors.request.use((config) => {
      this.stashConfig = config;
      const ACCESS_TOKEN = storage.get("access_token");
      if (ACCESS_TOKEN && !notUseTokenUrl.includes(config.url)) {
        if (option.tokenName === "Authorization") {
          config["headers"]["Authorization"] = `Bearer ${ACCESS_TOKEN}`;
        } else {
          config["headers"]["token"] = ACCESS_TOKEN;
        }
      }
      if (!config["headers"]["Content-Type"]) {
        config["headers"]["Content-Type"] =
          option.contentType || "application/json; charset=UTF-8";
      }
      return config;
    });
    //响应拦截器
    instance.interceptors.response.use(
      (res) => {
        return new Promise((resolve, reject) => {
          switch (res.data.code) {
            case 0:
              resolve(res);
              break;
            case -1:
              instance = ElMessage.error(res.data.msg);
              setTimeout(() => {
                instance.close();
              }, 1000);
              break;
            case 101:
            case 102:
              this.refreshToken(res.config, option, resolve);
              break;
            case 103:
              // 登录页面
              instance = ElMessage.error(res.data.msg);
              setTimeout(() => {
                instance.close();
              }, 1000);
              window.location.href = "/nc/iop/#/";
              // router.replace("/login");
              break;
          }
          resolve(res);
        });
      },
      (err) => {
        console.log("err ===>", err);
        return new Promise((resolve, reject) => {
          // let instance = null;
          switch (err.response.status) {
            case 401:
              instance = ElMessage.error(err.response.data.error_description);
              setTimeout(() => {
                instance.close();
              }, 1000);
              break;
          }
          resolve(err);
        });
      }
    );
  }
  refreshToken(config, option, resolve) {
    this.requestArr.push(() => {
      resolve(this.request(config, option));
    });
    if (!this.isRefreshing) {
      this.isRefreshing = true;
      const current_admin = storage.get("current_admin");
      const refreshToken = current_admin.refresh_token;
      const userStore = useUserStore();
      getRefresh({
          client_id: "CippWebApp",
          client_secret: "CippWebApp",
          grant_type: "refresh_token",
          refresh_token: refreshToken,
        })
        .then((res) => {
          switch (res.status) {
            case 200:
              if (res.data.scope == "all") {
                userStore.setInfo(res.data);
                userStore.setToken(res.data.access_token);
              }
              this.requestArr.map((MT) => {
                MT();
              });
              this.requestArr = [];
              break;
            default:
              wx.showToast({
                title: "系统繁忙！",
                icon: "error"
              });
          }
        })
        .finally(() => {
          this.isRefreshing = false;
        });
    }
  }
  get(config) {
    return this.request({
      ...config,
      method: "GET"
    }, this.curOption);
  }
  post(config) {
    return this.request({
      ...config,
      method: "POST"
    }, this.curOption);
  }
  delete(config) {
    return this.request({
      ...config,
      method: "DELETE"
    }, this.curOption);
  }
  put(config) {
    return this.request({
      ...config,
      method: "PUT"
    }, this.curOption);
  }
}

class httpRequest extends Request {
  constructor(optionName) {
    super();
    this.curOption = this[optionName];
  }
}

let http = new httpRequest("http1");
let http2 = new httpRequest("http2");
let http3 = new httpRequest("http3");
let http4 = new httpRequest("http4");

export {
  http,
  http2,
  http3,
  http4
};